package com.jiaz.controller;

import com.jiaz.algorithm.ItemAlgorithm;
import com.jiaz.algorithm.PrecisionRecall;
import com.jiaz.algorithm.UserAlgorithm;
import com.jiaz.dto.PostionScoreDto;
import com.jiaz.entity.Postion;
import com.jiaz.mapper.PostionMapper;
import com.jiaz.untils.ResultWrap;
import com.jiaz.untils.ResponseBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * @author jiajiazi
 * @version 1.0
 * @date 2022/5/11 1:26
 */
@RestController
@Slf4j
@RequestMapping("/algorithm**")
public class AlgorithmController {

    @Autowired
    private UserAlgorithm userAlgorithm;

    @Autowired
    private ItemAlgorithm itemAlgorithm;

    @Autowired
    private PrecisionRecall precisionRecall;

    @Autowired
    private PostionMapper postionMapper;


    @RequestMapping("/loadUserCache")
    public ResponseBean loadUserCacheFirst() {
        if (userAlgorithm.userPostionCheckIn == null || userAlgorithm.closeNodes == null) {
            userAlgorithm.freqImproveAlgorithm();
        }
        return ResponseBean.success("load to cache successful");
    }

    @RequestMapping("/getUserCheckRecomend")
    public ResponseBean userCheckRecomend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        PostionScoreDto[] postionScoreDtos = userAlgorithm.originAlgorithmScore(userId, venueId, topK);

        return ResponseBean.success(ResultWrap.userWrap(postionScoreDtos, venueId, postionMapper));
    }

    @RequestMapping("/getUserFreqRecomend")
    public ResponseBean userFreqRecomend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        PostionScoreDto[] postionScoreDtos = userAlgorithm.freqImproveAlgorithmScore(userId, venueId, topK);

        return ResponseBean.success(ResultWrap.userWrap(postionScoreDtos, venueId, postionMapper));
    }

    @RequestMapping("/getUserWPRRecomend")
    public ResponseBean userWPRRecomend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        PostionScoreDto[] postionScoreDtos = userAlgorithm.PG_gorithmScore(userId, venueId, topK);

        return ResponseBean.success(ResultWrap.userWrap(postionScoreDtos, venueId, postionMapper));
    }

    @RequestMapping("/loadItemCache")
    public ResponseBean loadItemCache() {
        if (itemAlgorithm.itemCheckInUsers == null || itemAlgorithm.closeWeightSum == null || itemAlgorithm.closeNod == null) {
            itemAlgorithm.originAlgorithm();
        }
        return ResponseBean.success("load to cache successful");
    }

    @RequestMapping("/getItemkRecomend")
    public ResponseBean itemkRecomend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        PostionScoreDto[] postionScoreDtos = itemAlgorithm.originAlgorithmScore(userId, venueId, topK);

        return ResponseBean.success(ResultWrap.userWrap(postionScoreDtos, venueId, postionMapper));
    }

    @RequestMapping("/getItemWPRRecomend")
    public ResponseBean itemWPRRecomend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        PostionScoreDto[] postionScoreDtos = itemAlgorithm.PG_gorithmScore(userId, venueId, topK);

        return ResponseBean.success(ResultWrap.userWrap(postionScoreDtos, venueId, postionMapper));
    }

    @RequestMapping("/getUserAllRecommend")
    public ResponseBean userAllRecommend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        ArrayList<Map<String, Object>> res = new ArrayList<>();

        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        Map<String, Object> map4 = new HashMap<>();
        ArrayList<Double[]> arr = new ArrayList<>();
        Postion postion1 = postionMapper.selectById(venueId);
        arr.add(new Double[]{postion1.getLon(), postion1.getLat()});
        map1.put("type", "self");
        map1.put("list", arr);
        res.add(map1);
        PostionScoreDto[] postionScoreDtos1 = userAlgorithm.originAlgorithmScore(userId, venueId, topK);
        ArrayList<Integer> param1 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos1) {
            param1.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList1 = postionMapper.selectBatchIds(param1);
        ArrayList<Double[]> arr1 = new ArrayList<>();
        for (Postion postion : postionList1) {
            arr1.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map2.put("type", "check");
        map2.put("list", arr1);
        res.add(map2);

        PostionScoreDto[] postionScoreDtos2 = userAlgorithm.freqImproveAlgorithmScore(userId, venueId, topK);
        ArrayList<Integer> param2 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos2) {
            param2.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList2 = postionMapper.selectBatchIds(param2);
        ArrayList<Double[]> arr2 = new ArrayList<>();
        for (Postion postion : postionList2) {
            arr2.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map3.put("type", "freq");
        map3.put("list", arr2);
        res.add(map3);

        PostionScoreDto[] postionScoreDtos3 = userAlgorithm.PG_gorithmScore(userId, venueId, topK);
        ArrayList<Integer> param3 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos3) {
            param3.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList3 = postionMapper.selectBatchIds(param3);
        ArrayList<Double[]> arr3 = new ArrayList<>();
        for (Postion postion : postionList3) {
            arr3.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map4.put("type", "wpr");
        map4.put("list", arr3);
        res.add(map4);
        return ResponseBean.success(res);
    }

    @RequestMapping("/getItemAllRecommend")
    public ResponseBean itemAllRecommend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        ArrayList<Map<String, Object>> res = new ArrayList<>();

        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        ArrayList<Double[]> arr = new ArrayList<>();
        Postion postion1 = postionMapper.selectById(venueId);
        arr.add(new Double[]{postion1.getLon(), postion1.getLat()});
        map1.put("type", "self");
        map1.put("list", arr);
        res.add(map1);
        PostionScoreDto[] postionScoreDtos1 = itemAlgorithm.originAlgorithmScore(userId, venueId, topK);
        ArrayList<Integer> param1 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos1) {
            param1.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList1 = postionMapper.selectBatchIds(param1);
        ArrayList<Double[]> arr1 = new ArrayList<>();
        for (Postion postion : postionList1) {
            arr1.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map2.put("type", "normal");
        map2.put("list", arr1);
        res.add(map2);

        PostionScoreDto[] postionScoreDtos2 = itemAlgorithm.PG_gorithmScore(userId, venueId, topK);
        ArrayList<Integer> param2 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos2) {
            param2.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList2 = postionMapper.selectBatchIds(param2);
        ArrayList<Double[]> arr2 = new ArrayList<>();
        for (Postion postion : postionList2) {
            arr2.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map3.put("type", "wpr");
        map3.put("list", arr2);
        res.add(map3);

        return ResponseBean.success(res);
    }

    @RequestMapping("/getFinalRecommend")
    public ResponseBean finalRecommend(Integer userId, Integer venueId, Integer topK) {
        if (userId == null || venueId == null) {
            return ResponseBean.error(4008, "参数错误(空值或为0)");
        }
        if (topK == null || topK < 1) {
            topK = 5;
        }
        ArrayList<Map<String, Object>> res = new ArrayList<>();

        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        ArrayList<Double[]> arr = new ArrayList<>();
        Postion postion1 = postionMapper.selectById(venueId);
        arr.add(new Double[]{postion1.getLon(), postion1.getLat()});
        map1.put("type", "self");
        map1.put("list", arr);
        res.add(map1);
        PostionScoreDto[] postionScoreDtos1 = precisionRecall.getWPRScore(userId, venueId, topK, 0.6);
        ArrayList<Integer> param1 = new ArrayList<>();
        for (PostionScoreDto postionScoreDto : postionScoreDtos1) {
            param1.add(postionScoreDto.getVenueId());
        }
        List<Postion> postionList1 = postionMapper.selectBatchIds(param1);
        ArrayList<Double[]> arr1 = new ArrayList<>();
        for (Postion postion : postionList1) {
            arr1.add(new Double[]{postion.getLon(), postion.getLat()});
        }
        map2.put("type", "wpr");
        map2.put("list", arr1);
        res.add(map2);

        return ResponseBean.success(res);
    }
}
